
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

namespace GameLogic
{
    [AddComponentMenu("UI/Guide/Mask Component")]
    public class MaskComponent : MonoBehaviour
    {
        [SerializeField] private Material m_Material;
        [SerializeField] private float m_AnimationDuration = 0.3f;
        [SerializeField] private AnimationType m_DefaultAnimationType = AnimationType.Scale;
        
        private Coroutine m_AnimationCoroutine;
        private float m_CurrentAnimProgress = 1f;
        
        // 挖洞区域类型
        public enum HoleShape
        {
            Rectangle = 0,
            Circle = 1,
            RoundedRectangle = 2
        }
        
        // 动画类型
        public enum AnimationType
        {
            Scale = 0,
            Fade = 1
        }
        
        // 挖洞区域参数
        private Vector4 m_HoleCenter = new Vector4(0.5f, 0.5f, 0, 0);
        private Vector4 m_HoleSize = new Vector4(0.1f, 0.1f, 0, 0);
        private HoleShape m_HoleShape = HoleShape.Circle;
        private float m_CornerRadius = 0.05f;
        private float m_Softness = 0f;

        public void SetMask(bool isMask)
        {
            if (isMask)
            {
                gameObject.SetActive(true);
                PlayShowAnimation();
            }
            else
            {
                PlayHideAnimation(() => gameObject.SetActive(false));
            }
        }

        public void SetMaterial(Material material)
        {
            m_Material = material;
            ApplyMaterialProperties();
        }

        public void SetHoleRectangle(Rect rect){
            SetHoleRectangle(rect.position, rect.size);
        }

        /// <summary>
        /// 设置挖洞区域（矩形）
        /// </summary>
        /// <param name="center">中心位置（0-1归一化坐标）</param>
        /// <param name="size">大小（0-1归一化坐标）</param>
        public void SetHoleRectangle(Vector2 center, Vector2 size)
        {
            m_HoleCenter = new Vector4(center.x, center.y, 0, 0);
            m_HoleSize = new Vector4(size.x, size.y, 0, 0);
            m_HoleShape = HoleShape.Rectangle;
            ApplyMaterialProperties();
        }

        /// <summary>
        /// 设置挖洞区域（圆形）
        /// </summary>
        /// <param name="center">中心位置（0-1归一化坐标）</param>
        /// <param name="radius">半径（0-1归一化坐标）</param>
        public void SetHoleCircle(Vector2 center, float radius)
        {
            m_HoleCenter = new Vector4(center.x, center.y, 0, 0);
            m_HoleSize = new Vector4(radius * 2, radius * 2, 0, 0);
            m_HoleShape = HoleShape.Circle;
            ApplyMaterialProperties();
        }

        /// <summary>
        /// 设置挖洞区域（圆角矩形）
        /// </summary>
        /// <param name="center">中心位置（0-1归一化坐标）</param>
        /// <param name="size">大小（0-1归一化坐标）</param>
        /// <param name="cornerRadius">圆角半径</param>
        public void SetHoleRoundedRectangle(Vector2 center, Vector2 size, float cornerRadius)
        {
            m_HoleCenter = new Vector4(center.x, center.y, 0, 0);
            m_HoleSize = new Vector4(size.x, size.y, 0, 0);
            m_HoleShape = HoleShape.RoundedRectangle;
            m_CornerRadius = cornerRadius;
            ApplyMaterialProperties();
        }

        /// <summary>
        /// 设置挖洞区域（基于RectTransform）
        /// </summary>
        /// <param name="targetRect">目标RectTransform</param>
        /// <param name="shape">挖洞形状</param>
        /// <param name="padding">额外边距</param>
        public void SetHoleFromRectTransform(RectTransform targetRect, HoleShape shape = HoleShape.Rectangle, Vector2? padding = null)
        {
            if (targetRect == null || m_Material == null) return;

            var maskRect = transform as RectTransform;
            if (maskRect == null) return;

            // 获取parent的RectTransform
            var parentRect = transform.parent as RectTransform;
            
            // 计算目标矩形在遮罩中的归一化坐标
            Vector2 targetCorners = new Vector2(targetRect.rect.width, targetRect.rect.height);
            
            // 考虑Canvas的缩放
            Vector2 targetSize = new Vector2(
                targetCorners.x * 1 / parentRect.rect.width,
                targetCorners.y * 1 / parentRect.rect.height
            );
            
            Vector2 targetCenter = new Vector2(
                targetRect.anchoredPosition.x / maskRect.rect.width + 0.5f,
                targetRect.anchoredPosition.y / maskRect.rect.height + 0.5f
            );

            // 应用边距
            if (padding.HasValue)
            {
                targetSize += padding.Value * 2;
            }

            // 根据形状设置挖洞区域
            switch (shape)
            {
                case HoleShape.Circle:
                    float radius = Mathf.Max(targetSize.x, targetSize.y) * 0.5f;
                    SetHoleCircle(targetCenter, radius);
                    break;
                case HoleShape.RoundedRectangle:
                    float cornerRadius = Mathf.Min(targetSize.x, targetSize.y) * 0.1f;
                    SetHoleRoundedRectangle(targetCenter, targetSize, cornerRadius);
                    break;
                default:
                    SetHoleRectangle(targetCenter, targetSize);
                    break;
            }
        }

        /// <summary>
        /// 播放出现动画
        /// </summary>
        public void PlayShowAnimation(AnimationType? animType = null)
        {
            var type = animType ?? m_DefaultAnimationType;
            PlayAnimation(0f, 1f, type);
        }

        /// <summary>
        /// 播放消失动画
        /// </summary>
        public void PlayHideAnimation(AnimationCompleteCallback onComplete = null, AnimationType? animType = null)
        {
            var type = animType ?? m_DefaultAnimationType;
            PlayAnimation(1f, 0f, type, onComplete);
        }

        /// <summary>
        /// 动画完成回调
        /// </summary>
        public delegate void AnimationCompleteCallback();

        /// <summary>
        /// 播放动画
        /// </summary>
        private void PlayAnimation(float from, float to, AnimationType animType, AnimationCompleteCallback onComplete = null)
        {
            if (m_AnimationCoroutine != null)
            {
                StopCoroutine(m_AnimationCoroutine);
            }

            m_AnimationCoroutine = StartCoroutine(AnimationCoroutine(from, to, animType, onComplete));
        }

        /// <summary>
        /// 动画协程
        /// </summary>
        private IEnumerator AnimationCoroutine(float from, float to, AnimationType animType, AnimationCompleteCallback onComplete)
        {
            float elapsed = 0f;
            
            while (elapsed < m_AnimationDuration)
            {
                elapsed += Time.deltaTime;
                float progress = elapsed / m_AnimationDuration;
                
                // 使用平滑曲线
                float smoothProgress = Mathf.SmoothStep(0f, 1f, progress);
                m_CurrentAnimProgress = Mathf.Lerp(from, to, smoothProgress);
                
                // 更新材质参数
                if (m_Material != null)
                {
                    m_Material.SetFloat("_AnimProgress", m_CurrentAnimProgress);
                    m_Material.SetFloat("_AnimType", (float)animType);
                }
                
                yield return null;
            }
            
            m_CurrentAnimProgress = to;
            if (m_Material != null)
            {
                m_Material.SetFloat("_AnimProgress", m_CurrentAnimProgress);
            }
            
            onComplete?.Invoke();
            m_AnimationCoroutine = null;
        }

        /// <summary>
        /// 应用材质属性
        /// </summary>
        private void ApplyMaterialProperties()
        {
            if (m_Material == null) return;

            m_Material.SetVector("_HoleCenter", m_HoleCenter);
            m_Material.SetVector("_HoleSize", m_HoleSize);
            m_Material.SetFloat("_HoleShape", (float)m_HoleShape);
            m_Material.SetFloat("_CornerRadius", m_CornerRadius);
            m_Material.SetFloat("_Softness", m_Softness);
            m_Material.SetFloat("_AnimProgress", m_CurrentAnimProgress);
            m_Material.SetFloat("_AnimType", (float)m_DefaultAnimationType);
        }

        public void OnStart()
        {
            if (m_Material == null)
            {
                // 尝试从Renderer获取材质
                if (TryGetComponent<Renderer>(out var renderer))
                {
                    m_Material = renderer.material;
                }
                // 尝试从Image获取材质
                else if (TryGetComponent<Image>(out var image))
                {
                    m_Material = image.material;
                }
            }
        }
        
        /// <summary>
        /// OnDestroy
        /// </summary>
        void OnDestroy()
        {
            if (m_AnimationCoroutine != null)
            {
                StopCoroutine(m_AnimationCoroutine);
            }
        }
    }
}